import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error, mean_squared_error
import matplotlib.pyplot as plt
"""
数据特征：
时间特征：小时、星期、月份、是否周末
市场因素：电力需求、温度、燃料价格
滞后特征：前24小时电价（捕捉时间依赖性）
模型选择：
使用随机森林回归处理非线性关系
适合处理混合特征类型和时间序列特性
"""
# 生成模拟数据（实际应用时应使用真实数据）
def generate_sample_data(days=365):
    dates = pd.date_range(start="2020-01-01", periods=days*24, freq="H")
    data = pd.DataFrame({
        'DateTime': dates,
        'Price': np.random.normal(loc=50, scale=20, size=len(dates)).cumsum(),  # 模拟电价
        'Demand': np.random.randint(1000, 5000, len(dates)),  # 模拟电力需求
        'Temperature': np.random.uniform(10, 35, len(dates)),  # 温度
        'FuelPrice': np.random.normal(30, 5, len(dates))  # 燃料价格
    })
    return data

# 创建时间序列特征
def create_features(df):
    df = df.copy()
    df['Hour'] = df['DateTime'].dt.hour
    df['DayOfWeek'] = df['DateTime'].dt.dayofweek
    df['Month'] = df['DateTime'].dt.month
    df['IsWeekend'] = df['DayOfWeek'].isin([5,6]).astype(int)
    return df

# 生成数据
data = generate_sample_data(365)
data = create_features(data)

# 添加滞后特征（前24小时电价）
data['Price_Lag24'] = data['Price'].shift(24)
data = data.dropna()

# 定义特征和目标变量
features = ['Hour', 'DayOfWeek', 'Month', 'IsWeekend',
            'Demand', 'Temperature', 'FuelPrice', 'Price_Lag24']
target = 'Price'

# 划分训练集和测试集
X = data[features]
y = data[target]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# 训练模型
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# 预测和评估
predictions = model.predict(X_test)
mae = mean_absolute_error(y_test, predictions)
rmse = np.sqrt(mean_squared_error(y_test, predictions))

print(f"MAE: {mae:.2f}")
print(f"RMSE: {rmse:.2f}")

# 可视化结果
plt.figure(figsize=(12,6))
plt.plot(data['DateTime'][-len(y_test):], y_test.values, label='Actual')
plt.plot(data['DateTime'][-len(y_test):], predictions, label='Predicted')
plt.title('Electricity Price Prediction')
plt.xlabel('Date')
plt.ylabel('Price ($/MWh)')
plt.legend()
plt.show()